/*
 *  pci.h
 *  xcode
 *
 *  Created by Emiel Goor,van on 24-01-08.
 *  Copyright 2008 __MyCompanyName__. All rights reserved.
 *
 */

// pci bus main header

#ifndef PCI_H
#define PCI_H

#include "common.h"

// useful types
typedef u8int uint8_t;
typedef u16int uint16_t;
typedef u32int uint32_t;
typedef unsigned long uint64_t;

// useful constants - taken with permission from ominOS source code
#define PCIBIOS_BIOS_PRESENT			0xb101

#define PCI_HEADER_TYPE_NORMAL			0
#define PCI_HEADER_TYPE_BRIDGE			1
#define PCI_HEADER_TYPE_CARDBUS			2

#define PCI_COMMAND						0x04
#define PCI_STATUS						0x06
#define PCI_IRQ_LINE					0x3C
#define PCI_IRQ_PIN						0x3D
#define PCI_SUBSYSTEM_VENDOR_ID			0x2C
#define PCI_SUBSYSTEM_ID				0x2E
#define PCI_LATENCY_TIMER				0x0D
#define PCI_CAPABILITY_LIST				0x34
#define PCI_CB_CAPABILITY_LIST			0x14
#define PCI_CACHE_LINE_SIZE				0x0C
#define PCI_CB_SUBSYSTEM_VENDOR_ID		0x40
#define PCI_CB_SUBSYSTEM_ID				0x42
#define PCI_ROM_ADDRESS					0x30
#define PCI_ROM_ADDRESS_1				0x38

#define PCI_BASE_ADDRESS_0				0x10
#define PCI_BASE_ADDRESS_SPACE			0x01
#define PCI_BASE_ADDRESS_SPACE_MEMORY	0x00
#define PCI_IO_RESOURCE_MEM				0x00
#define PCI_IO_RESOURCE_IO				0x01

#define PCI_ROM_ADDRESS_MASK			(~0x7FFUL)
#define PCI_BASE_ADDRESS_MEM_MASK		(~0x0FUL )
#define PCI_BASE_ADDRESS_IO_MASK		(~0x03UL )
#define PCI_PM_CTRL_STATE_MASK			( 0x0003 )

#define PCI_ROM_ADDRESS_ENABLE			0x01
#define PCI_COMMAND_IO					0x01
#define PCI_COMMAND_MEMORY				0x02
#define PCI_COMMAND_MASTER				0x04

// return codes
#define SUCCESSFUL						0x00
#define DEVICE_NOT_FOUND				0x86

// pci device type
typedef struct _pciDev_t
{
	uint16_t vendor_id;
	uint16_t device_id;
	
	uint16_t command;
	uint16_t status;
	
	uint8_t revision_id;
	uint8_t interface;
	uint8_t sub_class;
	uint8_t base_class;
	
	uint8_t cache_line_size;
	uint8_t latency_timer;
	uint8_t header_type;
	uint8_t bist;

	uint8_t bus;
	uint8_t dev;
	uint8_t func;

	uint8_t irq;
	uint32_t base[6];
	uint32_t size[6];
	uint8_t type[6];
	uint32_t rom_base;
	uint32_t rom_size;

	uint16_t subsys_vendor;
	uint16_t subsys_device;

	uint8_t current_state;
} pciDev_t;

// initializes the PCI bus
void InitPCI();

// gets a device by its id
pciDev_t *pciGetDeviceById(uint16_t vendor, uint32_t device, int index);

#endif // PCI_H
